#include "plugin.h"

// Qt Includes
#include <QtDebug>
#include <QDomElement>
#include <QObject>

/////////////////////////////////////////////////////////////////////
// Static Member Functions
/////////////////////////////////////////////////////////////////////
CPlugin::tPluginType CPlugin::pluginTypeFromString(const QString &strPluginType)
{
	if(strPluginType == QObject::tr("scanner"))
		return PLUGIN_TYPE_SCANNER;

	return PLUGIN_TYPE_NONE;
}

QString CPlugin::pluginTypeToString(tPluginType ePluginType)
{
	switch(ePluginType)
	{
		case PLUGIN_TYPE_SCANNER:
			return QObject::tr("scanner");

		default:
			return QObject::tr("none");
	}
}
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
// Construction & Destruction
/////////////////////////////////////////////////////////////////////
CPlugin::CPlugin(const QString &strPluginName, tPluginType ePluginType, const QString &strDescription)
	: m_strName(strPluginName),
	  m_ePluginType(ePluginType),
	  m_strDescription(strDescription)
{

}

CPlugin::CPlugin()
	: m_ePluginType(PLUGIN_TYPE_NONE)
{

}
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
// Member Functions
/////////////////////////////////////////////////////////////////////
bool CPlugin::loadFromXml(const QDomElement &xmlElement)
{
	if(xmlElement.isNull())
		return false;

	// We cache the properties of the plugin element so that we set them all
	// or we don't set any at all.
	QString strPluginName, strDescription;
	tPluginType ePluginType = PLUGIN_TYPE_NONE;

	// QDomNodeList doesn't work with forEach, which is a surprising decision by Qt.
	const QDomNodeList lstElementNodes = xmlElement.childNodes();
	const int nElementNodeCount = lstElementNodes.count();

	for(int i = 0; i < nElementNodeCount; i++)
	{
		const QDomNode xmlElementNode = lstElementNodes.at(i);

		if(xmlElementNode.isNull())
			continue;

		const QString strElementNodeName = xmlElementNode.nodeName();

		if(strElementNodeName == QObject::tr("name"))
		{
			if(xmlElementNode.childNodes().count() != 1)
				break;

			strPluginName = xmlElementNode.firstChild().nodeValue().trimmed();
			continue;
		}

		if(strElementNodeName == QObject::tr("type"))
		{
			if(xmlElementNode.childNodes().count() != 1)
				break;

			ePluginType = pluginTypeFromString(xmlElementNode.firstChild().nodeValue().trimmed());
			continue;
		}

		if(strElementNodeName == QObject::tr("description"))
		{
			if(xmlElementNode.childNodes().count() != 1)
				break;

			strDescription = xmlElementNode.firstChild().nodeValue().trimmed();
			continue;
		}
	}

	// If we didn't manage to obtain all the expected elements, we've failed to load
	// the plugin from Xml.
	if(strPluginName.isEmpty() || (ePluginType == PLUGIN_TYPE_NONE))
		return false;

	m_strName = strPluginName;
	m_ePluginType = ePluginType;
	m_strDescription = strDescription;

	return true;
}

QDomElement CPlugin::saveToXml(QDomDocument &xmlDocument, bool bConfigOnly/* = false*/) const
{
	QDomElement xmlElement = xmlDocument.createElement(QObject::tr("plugin"));
	QDomElement xmlNameElement = xmlDocument.createElement(QObject::tr("name"));;
	QDomElement xmlTypeElement = xmlDocument.createElement(QObject::tr("type"));;

	QDomText xmlNameText = xmlDocument.createTextNode(m_strName);
	QDomText xmlTypeText = xmlDocument.createTextNode(pluginTypeToString(m_ePluginType));

	xmlNameElement.appendChild(xmlNameText);
	xmlElement.appendChild(xmlNameElement);

	xmlTypeElement.appendChild(xmlTypeText);
	xmlElement.appendChild(xmlTypeElement);

	if(!bConfigOnly)
	{
		QDomText xmlDescriptionText = xmlDocument.createTextNode(m_strDescription);
		QDomElement xmlDescriptionElement = xmlDocument.createElement(QObject::tr("description"));;

		xmlDescriptionElement.appendChild(xmlDescriptionText);
		xmlElement.appendChild(xmlDescriptionElement);
	}

	return xmlElement;
}
/////////////////////////////////////////////////////////////////////
